<html><head><meta charset="utf-8"><title>搭建后台界面布局和结合Vuex实现完整登录流程-慕课专栏</title>
			<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
			<meta name="renderer" content="webkit">
			<meta property="qc:admins" content="77103107776157736375">
			<meta property="wb:webmaster" content="c4f857219bfae3cb">
			<meta http-equiv="Access-Control-Allow-Origin" content="*">
			<meta http-equiv="Cache-Control" content="no-transform ">
			<meta http-equiv="Cache-Control" content="no-siteapp">
			<link rel="apple-touch-icon" sizes="76x76" href="https://www.imooc.com/static/img/common/touch-icon-ipad.png">
			<link rel="apple-touch-icon" sizes="120x120" href="https://www.imooc.com/static/img/common/touch-icon-iphone-retina.png">
			<link rel="apple-touch-icon" sizes="152x152" href="https://www.imooc.com/static/img/common/touch-icon-ipad-retina.png">
			<link href="https://moco.imooc.com/captcha/style/captcha.min.css" rel="stylesheet">
			<link rel="stylesheet" href="https://www.imooc.com/static/moco/v1.0/dist/css/moco.min.css?t=201907021539" type="text/css">
			<link rel="stylesheet" href="https://www.imooc.com/static/lib/swiper/swiper-3.4.2.min.css?t=201907021539">
			<link rel="stylesheet" href="https://static.mukewang.com/static/css/??base.css,common/common-less.css?t=2.5,column/zhuanlanChapter-less.css?t=2.5,course/inc/course_tipoff-less.css?t=2.5?v=201907051055" type="text/css">
			<link charset="utf-8" rel="stylesheet" href="https://www.imooc.com/static/lib/ueditor/themes/imooc/css/ueditor.css?v=201907021539"><link rel="stylesheet" href="https://www.imooc.com/static/lib/baiduShare/api/css/share_style0_16.css?v=6aba13f0.css"></head>
			<body><div id="main">

<div class="container clearfix" id="top" style="display: block; width: 1134px;">
    
    <div class="center_con js-center_con l" style="width: 1134px;">
        <div class="article-con">
                            <!-- 买过的阅读 -->
                <div class="map">
                    <a href="/read" target="_blank"><i class="imv2-feather-o"></i></a>
                    <a href="/read/35" target="_blank">零基础学透 TypeScript</a>
                    <a href="" target="_blank">
                        <span>
                            / 6-4 搭建后台界面布局和结合Vuex实现完整登录流程
                        </span>
                    </a>
                </div>

            


            <div class="art-title" style="margin-top: 0px;">
                搭建后台界面布局和结合Vuex实现完整登录流程
            </div>
            <div class="art-info">
                
                <span>
                    更新时间：2019-07-29 09:26:01
                </span>
            </div>
            <div class="art-top">
                                <img src="https://img.mukewang.com/5d37f64a00013ca706400359.jpg" alt="">
                                                <div class="famous-word-box">
                    <img src="https://www.imooc.com/static/img/column/bg-l.png" alt="" class="bg1 bg">
                    <img src="https://www.imooc.com/static/img/column/bg-r.png" alt="" class="bg2 bg">
                    <div class="famous-word">理想必须要人们去实现它，它不但需要决心和勇敢而且需要知识。<p class="author">——吴玉章</p></div>
                </div>
                            </div>
            <div class="art-content js-lookimg">
                <div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">本小节我们来搭建一个后台基本框架，所有的页面除了登录页，都在这个框架里展示，左侧显示菜单，右侧显示页面，我们先看下要实现的效果：</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;"><img src="http://img.mukewang.com/5d22b5ab0001232118020932.png" alt="图片描述" data-original="http://img.mukewang.com/5d22b5ab0001232118020932.png" class="" style="cursor: pointer;"></p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">接下来我们继续上个小节的节奏进行。在开始之前我们需要安装一个UI组件库，<a href="https://vue.ant.design/docs/vue/introduce-cn/">Ant Design Vue</a>，它是React版本的Ant Design组件库的Vue版本，因为Ant Design是使用TypeScript编写的，类型声明文件较为完善，而Ant Design Vue延用这些声明文件，所以可以更好地在TypeScript环境下使用。首先来安装它：<code>npm install ant-design-vue</code>。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">接下来我们在入口文件引入组件库及其样式，并且全局注册它：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token comment">// src/main.ts</span>
<span class="token comment">// ...</span>
<span class="token keyword">import</span> AntVue <span class="token keyword">from</span> <span class="token string">'ant-design-vue'</span>
<span class="token keyword">import</span> <span class="token string">'ant-design-vue/dist/antd.css'</span><span class="token punctuation">;</span>
Vue<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>AntVue<span class="token punctuation">)</span>
<span class="token comment">// ...</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">顺便修改一下<em>src/App.vue</em>的样式，我们在App.vue文件的样式里，增加如下样式，使页面具有高度：</p>
</div><div class="cl-preview-section"><pre class="  language-less"><code class="prism  language-less"><span class="token selector">html,body</span><span class="token punctuation">{</span>
    <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">100%</span><span class="token punctuation">;</span>
    <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">#app</span><span class="token punctuation">{</span>
    <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">100%</span><span class="token punctuation">;</span>
    <span class="token selector">.home</span><span class="token punctuation">{</span>
      <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">接下来我们在<em>src/components</em>文件夹下创建一个<em>TMain</em>文件夹，之所以叫这个，是因为根据Vue开发规范强烈建议组件名使用大写字母开头，然后使用驼峰形式命名，而且不要使用单个单词，应该统一加个前缀，所以我们这个框架组件叫做TMain，然后在<em>TMain</em>文件夹下创建一个<em>index.vue</em>文件。我们来使用单文件的形式编写组件。我们先只添加基本的代码：</p>
</div><div class="cl-preview-section"><pre class="  language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>t-main-wrap<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token comment">&lt;!-- 布局容器组件 --&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-layout</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">100%</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token comment">&lt;!-- 左侧容器组件 --&gt;</span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-layout-sider</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-layout-sider</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-layout</span><span class="token punctuation">&gt;</span></span>
            <span class="token comment">&lt;!-- 顶部容器组件 --&gt;</span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-layout-header</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">background</span><span class="token punctuation">:</span> <span class="token hexcode">#fff</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-layout-header</span><span class="token punctuation">&gt;</span></span>
            <span class="token comment">&lt;!-- 内容容器组件 --&gt;</span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-layout-content</span><span class="token punctuation">&gt;</span></span>
                <span class="token comment">&lt;!-- 路由视图渲染组件 --&gt;</span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>router-view</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>router-view</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-layout-content</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-layout</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-layout</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>ts<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token script language-javascript">
<span class="token keyword">import</span> <span class="token punctuation">{</span> Component<span class="token punctuation">,</span> Vue <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'vue-property-decorator'</span>

@<span class="token function">Component</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    name<span class="token punctuation">:</span> <span class="token string">'TMain'</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">TMain</span> <span class="token keyword">extends</span> <span class="token class-name">Vue</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>less<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token style language-css">
<span class="token selector"><span class="token class">.t-main-wrap</span></span><span class="token punctuation">{</span>
    <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">100%</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">然后修改下路由，这里需要用到嵌套路由，所有要在框架里展示的页面，都要作为子路由去配置，父路由的组件就是这里的TMain，我们来看下之前的路由配置如何修改：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token comment">// src/router/routes.ts</span>
<span class="token keyword">import</span> Home <span class="token keyword">from</span> <span class="token string">'../views/Home.vue'</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">[</span>
    <span class="token punctuation">{</span>
        path<span class="token punctuation">:</span> <span class="token string">'/'</span><span class="token punctuation">,</span>
        component<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'@/components/TMain/index.vue'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        children<span class="token punctuation">:</span> <span class="token punctuation">[</span>
        <span class="token punctuation">{</span>
            path<span class="token punctuation">:</span> <span class="token string">'/home'</span><span class="token punctuation">,</span>
            name<span class="token punctuation">:</span> <span class="token string">'home'</span><span class="token punctuation">,</span>
            component<span class="token punctuation">:</span> Home<span class="token punctuation">,</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{</span>
            path<span class="token punctuation">:</span> <span class="token string">'/about'</span><span class="token punctuation">,</span>
            name<span class="token punctuation">:</span> <span class="token string">'about'</span><span class="token punctuation">,</span>
            component<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'../views/About.vue'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        <span class="token punctuation">}</span>
        <span class="token punctuation">]</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">{</span>
        path<span class="token punctuation">:</span> <span class="token string">'/login'</span><span class="token punctuation">,</span>
        name<span class="token punctuation">:</span> <span class="token string">'login'</span><span class="token punctuation">,</span>
        component<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'../views/login/index'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">可以看到，我们要让home页和about页在框架内显示，所以作为TMain组件的子路由，登录页是不希望在框架内显示的，所以和TMain组件所在路由同级。修改路由保存成功后，此时如果你访问<strong>localhost:8080/#/home</strong>(端口需要看你实际端口为多少)，就会发现原来的home页在右侧区域内，但因为我们删掉了样式，所有样式有变化，效果如图：</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;"><img src="http://img.mukewang.com/5d22b59f000140fc18020838.png" alt="图片描述" data-original="http://img.mukewang.com/5d22b59f000140fc18020838.png" class="" style="cursor: pointer;"><br>
修改浏览器地址栏的url，改为<strong>localhost:8080/#/about</strong>，就会在右边区域展示about页的内容。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">接下来我们要添加左侧菜单，在左侧容器组件<code>&lt;a-layout-sider&gt;&lt;/a-layout-sider&gt;</code>中添加菜单：</p>
</div><div class="cl-preview-section"><pre class="  language-html"><code class="prism  language-html"><span class="token comment">&lt;!-- 省略部分代码 --&gt;</span>
<span class="token comment">&lt;!--src\components\TMain\index.vue--&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-layout-sider</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-menu</span>
                <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>handleClickMenu<span class="token punctuation">"</span></span>
                <span class="token attr-name">theme</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>dark<span class="token punctuation">"</span></span><span class="token style-attr language-css"><span class="token attr-name">
                <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">100%</span></span><span class="token punctuation">"</span></span>
                <span class="token attr-name">mode</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>inline<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-menu-item</span> <span class="token attr-name">key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>/home<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>首页<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-menu-item</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-menu-item</span> <span class="token attr-name">key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>/about<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>介绍页<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-menu-item</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-menu</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-layout-sider</span><span class="token punctuation">&gt;</span></span>
<span class="token comment">&lt;!-- 省略部分代码 --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>ts<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token script language-javascript">
<span class="token keyword">import</span> <span class="token punctuation">{</span> Component<span class="token punctuation">,</span> Vue <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'vue-property-decorator'</span>

@<span class="token function">Component</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    name<span class="token punctuation">:</span> <span class="token string">'TMain'</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">TMain</span> <span class="token keyword">extends</span> <span class="token class-name">Vue</span> <span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token function">handleClickMenu</span><span class="token punctuation">(</span><span class="token punctuation">{</span> item<span class="token punctuation">,</span> key<span class="token punctuation">,</span> keyPath <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>$router<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">现在再在浏览器看下，左侧有了两个菜单项，点击菜单项右边的页面会相应变化。但当我们刷新页面后，左侧菜单并不会高亮相应的菜单项，即使右侧显示的页面是相应的页面。所以这里我们就可以使用一下路由的一些数据，搭配AMenu组件的api。我们知道vue-router可以在组件中通过<code>lt;$route.path</code>即当前页面的路径，和我们在写菜单项的时候，给<code>&lt;a-menu-item&gt;&lt;/a-menu-item&gt;</code>设置的key属性是对应的，所以我们可以给<code>&lt;a-menu&gt;&lt;/a-menu&gt;</code>添加一个<code>selectedKeys</code>属性，它是一个数组，我们这里只需要如下设置即可：</p>
</div><div class="cl-preview-section"><pre class="  language-html"><code class="prism  language-html"><span class="token comment">&lt;!-- 省略部分代码 --&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-layout-sider</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-menu</span>
                <span class="token attr-name">:selected-keys</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>[this.$route.path]<span class="token punctuation">"</span></span>
                <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>handleClickMenu<span class="token punctuation">"</span></span>
                <span class="token attr-name">theme</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>dark<span class="token punctuation">"</span></span><span class="token style-attr language-css"><span class="token attr-name">
                <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">width</span><span class="token punctuation">:</span> <span class="token number">100%</span></span><span class="token punctuation">"</span></span>
                <span class="token attr-name">mode</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>inline<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
<span class="token comment">&lt;!-- 省略部分代码 --&gt;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">现在你选中任意一下进行页面跳转，然后刷新浏览器，你会发现菜单会高亮当前打开的页面对应的菜单项。利用路由对象还可以做很多事，比如可以根据路由对象的<code>matched</code>来实现面包屑，显示当前打开页面的层级关系等。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">下面我们增加一个用户头像，用户头像我们这里不用图片了，而是用用户名，这样我们可以演示如何结合TypeScript使用Vuex。点击用户头像显示下拉菜单，显示退出登录。点击退出登录后清掉保存的登录cookie信息。在<code>&lt;a-layout-header&gt;&lt;/a-layout-header&gt;</code>标签中添加一个带下拉菜单的用户头像：</p>
</div><div class="cl-preview-section"><pre class="  language-html"><code class="prism  language-html"><span class="token comment">&lt;!-- 省略部分代码 --&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-layout-header</span><span class="token style-attr language-css"><span class="token attr-name"> <span class="token attr-name">style</span></span><span class="token punctuation">="</span><span class="token attr-value"><span class="token property">background</span><span class="token punctuation">:</span> <span class="token hexcode">#fff</span><span class="token punctuation">;</span><span class="token property">text-align</span><span class="token punctuation">:</span> right<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-dropdown</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-avatar</span><span class="token punctuation">&gt;</span></span>USER<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-avatar</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-menu</span> <span class="token attr-name">slot</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>overlay<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-menu-item</span> <span class="token attr-name">key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>logout<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>退出登录<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-menu-item</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-menu</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-dropdown</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-layout-header</span><span class="token punctuation">&gt;</span></span>
<span class="token comment">&lt;!-- 省略部分代码 --&gt;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">现在你会发现顶部右侧有一个原型头像框，中间是我们这里写死的"USER"字符，鼠标放上去会出现下拉菜单。接下来我们补充一下前面的登录逻辑，登录成功之后返回用户ID，然后再通过用户ID去拿用户信息，将用户信息保存在store中，然后从用户信息中将用户名在这里展示。其实在实际开发中，登录接口调用成功登录后，会返回token，然后携带token去请求获取用户信息，我们这里简化逻辑了。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">首先修改下mock中登录接口拦截的逻辑，登录成功后返回用户ID：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token comment">// src/mock/index.ts</span>
Mock<span class="token punctuation">.</span><span class="token function">mock</span><span class="token punctuation">(</span><span class="token regex">/\/api\/user\/login/</span><span class="token punctuation">,</span> loginRes<span class="token punctuation">)</span>

<span class="token keyword">function</span> <span class="token function">loginRes</span><span class="token punctuation">(</span>req<span class="token punctuation">:</span> PostResInterface<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token punctuation">{</span> user_name<span class="token punctuation">,</span> password <span class="token punctuation">}</span> <span class="token operator">=</span> JSON<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>body<span class="token punctuation">)</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>user_name <span class="token operator">===</span> <span class="token string">'Lison'</span> <span class="token operator">&amp;&amp;</span> <span class="token function">String</span><span class="token punctuation">(</span>password<span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token string">'123456'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token function">success</span><span class="token punctuation">(</span><span class="token string">'登录成功'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> user_id<span class="token punctuation">:</span> <span class="token number">101</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token function">error</span><span class="token punctuation">(</span><span class="token number">1001</span><span class="token punctuation">,</span> <span class="token string">'用户名或密码错误'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">然后我们再添加一个返回用户信息接口的mock拦截：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token comment">// src/mock/index.ts</span>
Mock<span class="token punctuation">.</span><span class="token function">mock</span><span class="token punctuation">(</span><span class="token regex">/\/api\/user\/get_info/</span><span class="token punctuation">,</span> getInfoRes<span class="token punctuation">)</span>

<span class="token keyword">function</span> <span class="token function">getInfoRes</span><span class="token punctuation">(</span>req<span class="token punctuation">:</span> PostResInterface<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">success</span><span class="token punctuation">(</span><span class="token string">''</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
        user_name<span class="token punctuation">:</span> <span class="token string">'Lison'</span><span class="token punctuation">,</span>
        avatar<span class="token punctuation">:</span> <span class="token string">''</span><span class="token punctuation">,</span>
        email<span class="token punctuation">:</span> <span class="token string">'xxx@xx.com'</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">接下来在<em>src/api/user.ts</em>里封装获取信息接口调用方法：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token comment">// src/api/user.ts</span>
<span class="token keyword">interface</span> <span class="token class-name">GetInfoReqArguInterface</span> <span class="token punctuation">{</span>
    user_id<span class="token punctuation">:</span> <span class="token keyword">string</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> getInfoReq <span class="token operator">=</span> <span class="token punctuation">(</span>data<span class="token punctuation">:</span> GetInfoReqArguInterface<span class="token punctuation">)</span><span class="token punctuation">:</span> AxiosPromise<span class="token operator">&lt;</span>ResponseData<span class="token operator">&gt;</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> axios<span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
        url<span class="token punctuation">:</span> <span class="token string">'/api/user/get_info'</span><span class="token punctuation">,</span>
        data<span class="token punctuation">,</span>
        method<span class="token punctuation">:</span> <span class="token string">'POST'</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">然后我们要把原来写在<em>src/views/login/index.tsx</em>的login方法的逻辑写在store的actions里，然后这里通过dispatch调用。首先在<em>src/store/index.ts</em>文件中增加一个登录的actions：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token comment">// src/store/index.ts</span>
<span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">'vue'</span>
<span class="token keyword">import</span> Vuex <span class="token keyword">from</span> <span class="token string">'vuex'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> loginReq<span class="token punctuation">,</span>getInfoReq <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@/api/user'</span>
<span class="token keyword">import</span> Cookies <span class="token keyword">from</span> <span class="token string">'js-cookie'</span>

Vue<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>Vuex<span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">new</span> <span class="token class-name">Vuex<span class="token punctuation">.</span>Store</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    state<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        user_name<span class="token punctuation">:</span> <span class="token string">''</span><span class="token punctuation">,</span>
        email<span class="token punctuation">:</span> <span class="token string">''</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    mutations<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        <span class="token comment">// 设置存储在store里的用户信息</span>
        <span class="token function">setUserInfoMutations</span><span class="token punctuation">(</span>state<span class="token punctuation">,</span> info<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">const</span> <span class="token punctuation">{</span> user_name<span class="token punctuation">,</span> email <span class="token punctuation">}</span> <span class="token operator">=</span> info
            state<span class="token punctuation">.</span>user_name <span class="token operator">=</span> user_name
            state<span class="token punctuation">.</span>email <span class="token operator">=</span> email
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    actions<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        <span class="token function">loginActions</span><span class="token punctuation">(</span><span class="token punctuation">{</span> commit<span class="token punctuation">,</span> dispatch <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> user_name<span class="token punctuation">,</span> password <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> reject<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
                <span class="token function">loginReq</span><span class="token punctuation">(</span><span class="token punctuation">{</span> user_name<span class="token punctuation">,</span> password <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span>response<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span> <span class="token comment">// 首先调登录接口</span>
                    <span class="token keyword">const</span> <span class="token punctuation">{</span> data<span class="token punctuation">:</span> <span class="token punctuation">{</span> code<span class="token punctuation">,</span> msg<span class="token punctuation">,</span> data <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token operator">=</span> response
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>code <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">// 成功返回后，将token存到cookie中，然后携带token去请求获取信息接口</span>
                        Cookies<span class="token punctuation">.</span><span class="token keyword">set</span><span class="token punctuation">(</span><span class="token string">'token'</span><span class="token punctuation">,</span> <span class="token string">'value'</span><span class="token punctuation">)</span>
                        <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token string">'getInfoActions'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
                            <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                        <span class="token punctuation">}</span><span class="token punctuation">)</span>
                    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
                        console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span>
                    <span class="token punctuation">}</span>
                <span class="token punctuation">}</span><span class="token punctuation">)</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token function">getInfoActions</span><span class="token punctuation">(</span><span class="token punctuation">{</span> commit <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> reject<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
                <span class="token function">getInfoReq</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
                    <span class="token keyword">const</span> <span class="token punctuation">{</span> data<span class="token punctuation">:</span> <span class="token punctuation">{</span> code<span class="token punctuation">,</span> data <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token operator">=</span> res
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>code <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                        <span class="token function">commit</span><span class="token punctuation">(</span><span class="token string">'setUserInfoMutations'</span><span class="token punctuation">,</span> data<span class="token punctuation">)</span>
                        <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// 全部操作做完后，调用resolve方法</span>
                    <span class="token punctuation">}</span>
                <span class="token punctuation">}</span><span class="token punctuation">)</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">修改成功之后，我们需要在登录成功之后跳到home页，这个逻辑就放在login页，也就是<em>src/views/login/index.tsx</em>文件里去写。首先要在点击登录后，调用store里的这个actions：loginActions方法。这里需要安装一个插件：<code>npm install vuex-class</code>，我们需要用它来方便进行开发。安装好后，启动服务，我们修改<em>src/views/login/index.tsx</em>：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">import</span> <span class="token punctuation">{</span> Component<span class="token punctuation">,</span> Emit<span class="token punctuation">,</span> Prop<span class="token punctuation">,</span> Vue<span class="token punctuation">,</span> Watch <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'vue-property-decorator'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> State<span class="token punctuation">,</span> Action <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'vuex-class'</span>

@Component
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">LoginPage</span> <span class="token keyword">extends</span> <span class="token class-name">Vue</span> <span class="token punctuation">{</span>
    <span class="token comment">// ... 省略之前讲的部分代码</span>

    @<span class="token function">Action</span><span class="token punctuation">(</span><span class="token string">'loginActions'</span><span class="token punctuation">)</span> <span class="token keyword">public</span> loginAction <span class="token comment">// 这里通过@Action('loginActions')装饰器指定loginAction是store里的loginActions方法</span>

    <span class="token keyword">public</span> <span class="token function">login</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// 然后这里就可以直接调用loginAction方法</span>
        <span class="token comment">// 效果和this.$store.dispatch('loginActions', { 参数 })是一样的</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">loginAction</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
            user_name<span class="token punctuation">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>password<span class="token punctuation">,</span>
            password<span class="token punctuation">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>password
        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
            <span class="token comment">// 在store中的loginActions定义中，执行resolve方法的时机就是这里then中传入的这个函数执行的时机</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>$router<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">'/home'</span><span class="token punctuation">)</span> <span class="token comment">// 在这跳转到home页</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">protected</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">接下来我们登录成功之后，就会将用户信息保存在store中，所以我们可以在用户头像的地方用真实的用户名了。首先在TMain组件中引入这个state：</p>
</div><div class="cl-preview-section"><pre class="  language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>ts<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token script language-javascript">
<span class="token keyword">import</span> <span class="token punctuation">{</span> Component<span class="token punctuation">,</span> Vue <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'vue-property-decorator'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> State <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'vuex-class'</span>

@<span class="token function">Component</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    name<span class="token punctuation">:</span> <span class="token string">'TMain'</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">TMain</span> <span class="token keyword">extends</span> <span class="token class-name">Vue</span> <span class="token punctuation">{</span>
    @<span class="token function">State</span><span class="token punctuation">(</span><span class="token string">'user_name'</span><span class="token punctuation">)</span> <span class="token keyword">public</span> userName <span class="token comment">// 将store.state.user_name赋给userName</span>
<span class="token punctuation">}</span>
    <span class="token comment">// ...</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">然后你就可以在模板语法中使用了，我们使用userName替换上面写死的字符串"USER"：</p>
</div><div class="cl-preview-section"><pre class="  language-html"><code class="prism  language-html"><span class="token comment">&lt;!-- 省略部分代码 --&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-dropdown</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-avatar</span><span class="token punctuation">&gt;</span></span>{{ userName }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-avatar</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-menu</span> <span class="token attr-name">slot</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>overlay<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
<span class="token comment">&lt;!-- 省略部分代码 --&gt;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">这样，你就可以先清掉cookie重新登录，登陆后会进入home页，你会发现头像处已经显示的是我们获取到的用户名"Lison"了。但还有一个问题，存储在store中的数据是存在内存中的，当页面刷新后，内存中的数据就被清掉了，所以我们刷新后，需要重新调用获取用户信息的api请求，因为存在cookie中的token是不会随刷新被清掉的，所以我们实际中获取用户信息等都是携带token，然后后端根据token的信息，返回响应信息。这里我就不写这么复杂的逻辑了，我们在路由守卫里来处理这个逻辑：</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">在每次路由跳转的时候，判断store中的user_name是否为空字符串。如果为空字符串，可能是因为刷新页面导致的store中的user_name丢失，所以要重新请求获取用户信息：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">'vue'</span>
<span class="token keyword">import</span> Router <span class="token keyword">from</span> <span class="token string">'vue-router'</span>
<span class="token keyword">import</span> routes <span class="token keyword">from</span> <span class="token string">'./routes'</span>
<span class="token keyword">import</span> store <span class="token keyword">from</span> <span class="token string">'@/store'</span> <span class="token comment">// 引入store实例</span>
<span class="token keyword">import</span> Cookies <span class="token keyword">from</span> <span class="token string">'js-cookie'</span>

Vue<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>Router<span class="token punctuation">)</span>

<span class="token keyword">const</span> router <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Router</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  routes<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

<span class="token keyword">const</span> <span class="token function-variable function">turn</span> <span class="token operator">=</span> <span class="token punctuation">(</span>to<span class="token punctuation">,</span> <span class="token keyword">from</span><span class="token punctuation">,</span> next<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>to<span class="token punctuation">.</span>path <span class="token operator">===</span> <span class="token string">'/login'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 如果登录了然后访问login页，不做跳转，从哪来回哪去</span>
    <span class="token function">next</span><span class="token punctuation">(</span><span class="token keyword">from</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token comment">// 否则顺利跳转</span>
    <span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

router<span class="token punctuation">.</span><span class="token function">beforeEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span>to<span class="token punctuation">,</span> <span class="token keyword">from</span><span class="token punctuation">,</span> next<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> token <span class="token operator">=</span> Cookies<span class="token punctuation">.</span><span class="token keyword">get</span><span class="token punctuation">(</span><span class="token string">'token'</span><span class="token punctuation">)</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>token<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 如果token不为空字符串或者undefined，说明登录了</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>store<span class="token punctuation">.</span>state<span class="token punctuation">.</span>user_name<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 判断store.state.user_name是否为空，为空则需要获取</span>
      store<span class="token punctuation">.</span><span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token string">'getInfoActions'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token function">turn</span><span class="token punctuation">(</span>to<span class="token punctuation">,</span> <span class="token keyword">from</span><span class="token punctuation">,</span> next<span class="token punctuation">)</span> <span class="token comment">// 获取之后再跳转页面</span>
      <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
      <span class="token function">turn</span><span class="token punctuation">(</span>to<span class="token punctuation">,</span> <span class="token keyword">from</span><span class="token punctuation">,</span> next<span class="token punctuation">)</span> <span class="token comment">// 如果store.state.user_name不为空，直接跳转</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// 否则是没登录</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>to<span class="token punctuation">.</span>path <span class="token operator">===</span> <span class="token string">'/login'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// 如果没登录而且乖乖的到登录页去，轻松放行</span>
        <span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token comment">// 如果没登录还想去登录后的页面，打回登录页</span>
        <span class="token function">next</span><span class="token punctuation">(</span><span class="token string">'/login'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> router
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">现在无论你怎么刷新页面，你都可以看到头像显示的是正式的用户名。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">最后我们还有一个功能，就是退出登录。点击“退出登录”后，需要清楚cookie中存的token，然后跳到登录页，并且清空store中存的用户信息。首先我们在<em>src/components/TMain/index.vue</em>组件里，从<em>vuex-class</em>中引入Mutation装饰器：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">import</span> <span class="token punctuation">{</span> State<span class="token punctuation">,</span> Mutation <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'vuex-class'</span>
<span class="token keyword">import</span> Cookie <span class="token keyword">from</span> <span class="token string">'js-cookie'</span> <span class="token comment">// 注意，这个清楚cookie中token的逻辑，最好放到store中用专门的mutation去清除store中用户信息的同时清楚token</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">然后在组件类TMain中引入store中<code>setUserInfoMutations</code>方法，并且再增加两个方法：</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">handleClickAvatarMenu用于给头像下拉菜单绑定点击事件，logout用于做登出操作：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">TMain</span> <span class="token keyword">extends</span> <span class="token class-name">Vue</span> <span class="token punctuation">{</span>
    <span class="token comment">// ... 省略部分代码</span>
    @<span class="token function">Mutation</span><span class="token punctuation">(</span><span class="token string">'setUserInfoMutations'</span><span class="token punctuation">)</span> <span class="token keyword">public</span> setUserInfo
    <span class="token keyword">public</span> <span class="token function">handleClickAvatarMenu</span><span class="token punctuation">(</span><span class="token punctuation">{</span> item<span class="token punctuation">,</span> key<span class="token punctuation">,</span> keyPath <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>key <span class="token operator">===</span> <span class="token string">'logout'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">logout</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">public</span> <span class="token function">logout</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setUserInfo</span><span class="token punctuation">(</span><span class="token punctuation">{</span> user_name<span class="token punctuation">:</span> <span class="token string">''</span><span class="token punctuation">,</span> email<span class="token punctuation">:</span> <span class="token string">''</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
        Cookie<span class="token punctuation">.</span><span class="token keyword">set</span><span class="token punctuation">(</span><span class="token string">'token'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>$router<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">'/login'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">最后记得要在头像下拉菜单绑定这个handleClickAvatarMenu方法：</p>
</div><div class="cl-preview-section"><pre class="  language-html"><code class="prism  language-html"><span class="token comment">&lt;!-- 省略部分代码 --&gt;</span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-dropdown</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-avatar</span><span class="token punctuation">&gt;</span></span>{{ userName }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-avatar</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-menu</span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>handleClickAvatarMenu<span class="token punctuation">"</span></span> <span class="token attr-name">slot</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>overlay<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
                        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a-menu-item</span> <span class="token attr-name">key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>logout<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>退出登录<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-menu-item</span><span class="token punctuation">&gt;</span></span>
                    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-menu</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a-dropdown</span><span class="token punctuation">&gt;</span></span>
<span class="token comment">&lt;!-- 省略部分代码 --&gt;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">现在，点击头像下拉菜单的退出登录后，就会跳到登录页，而且不登录无法跳到Home等页。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">到这里，我们本小节的内容就讲完了。下个小节，我们将结合echarts和其他插件，封装几个组件，来搭建一个好看而且实用的仪表盘首页。</p>
</div></div>
            </div>
                            <!-- 买过的阅读 -->
                <div class="art-next-prev clearfix">
                                                                        <!-- 已买且开放 或者可以试读 -->
                            <a href="/read/35/article/373">
                                                    <div class="prev l clearfix">
                                <div class="icon l">
                                    <i class="imv2-arrow3_l"></i>
                                </div>
                                <p>
                                    实现登录页并用Mock响应请求
                                </p>
                            </div>
                        </a>
                                                                                            <!-- 已买且开放 或者可以试读 -->
                            <a href="/read/35/article/375">
                                                    <div class="next r clearfix">
                                <p>
                                    使用TypeScript开发Vue组件和使用Vue组件
                                </p>
                                <div class="icon r">
                                    <i class="imv2-arrow3_r"></i>
                                </div>

                            </div>
                        </a>
                                    </div>
                    </div>
        <div class="comments-con js-comments-con" id="coments_con">     <div class="number">精选留言 <span class="js-number">0</span></div>     <div class="comments">         <div class="input-fake js-showcommentModal">             欢迎在这里发表留言，作者筛选后可公开显示         </div>                      <div class="noData">                 <p>                     <i class="imv2-error_c"></i>                 </p>                 <p>目前暂无任何讨论</p>             </div>              </div>  </div>



    </div>
    
    
    

</div>
 
<!-- 专栏介绍页专栏评价 -->

<!-- 专栏介绍页底部三条评价 -->

<!-- 专栏阅读页弹层目录和介绍页页面目录 -->

<!-- 专栏阅读页发布回复 -->

<!-- 专栏阅读页发布评论 -->

<!-- 专栏阅读页底部评论 -->

<!-- 专栏阅读 单个 评论 -->

<!-- 新增回复和展开三条以外回复 -->

<!-- 立即订阅的弹窗 -->












</div></body></html>